/*****************************************************************************
 * $Workfile:: option_adjust.c                                               $
 * $Revision:: 19                                                            $
 * $JustDate::  3/21/12                                                      $
 *
 *    GENIE V ECU
 *    Option Configuration Interface
 *
 *****************************************************************************/

#include "main.h"       // must be first
#include "display.h"
#include "eeprom.h"
#include "joystick.h"
#include "nvm.h"
#include "option_adjust.h"
#include "speed_adjust.h"
#include "switches.h"
#include "calibrate_load_sensing.h"
#define OPTION_CLICK_TIME   SPEED_ADJUST_500MS  // 500 milliseconds
#define SAVE_TIME           SPEED_ADJUST_2SEC   // 2 second
#define FLASH_TIME          SPEED_ADJUST_300MS  // 300 milliseocnd second

#define OFF_BIT   0x80

#define SCAN_HORN_ON            (SW_HORN  && !OAD_Local.fHorn)
#define SCAN_HORN_OFF           (!SW_HORN  && OAD_Local.fHorn)
#define SCAN_RIGHT_ON           (SW_RIGHT && !OAD_Local.fRight)
#define SCAN_LEFT_ON            (SW_LEFT  && !OAD_Local.fLeft)
#define SCAN_LIFT_OFF           (!LIFT_DRIVE && OAD_Local.fLift)
#define SCAN_LIFT_ON            (LIFT_DRIVE && !OAD_Local.fLift)
#define SCAN_HIGH_OFF           (!SW_HIGH && OAD_Local.fHigh)

struct OAD OAD_Local;
GPS_DATA_t GPS_DATA;

#if 0
struct
{
   enum
   {
      SC = 0
      , SC_SHOW
      , SHOW_VALUE
      , HIGH_NIBBLE
      , LOW_NIBBLE
      , SHOW_VALUE1
      , VERIFY
      , WRITE_FAULT
	  , DATA1 
      , DATA2
      , DATA3
      , DATA4
      , DATA5
      , DATA6
      , DATA7
      , DATA8	
      // display states
      , SC_OFF          = (SC          | OFF_BIT)
      , SC_SHOW_OFF     = (SC_SHOW     | OFF_BIT)
      , SHOW_VALUE_OFF  = (SHOW_VALUE  | OFF_BIT)
      , HIGH_NIBBLE_OFF = (HIGH_NIBBLE | OFF_BIT)
      , LOW_NIBBLE_OFF  = (LOW_NIBBLE  | OFF_BIT)
      , SHOW_VALUE1_OFF = (SHOW_VALUE1 | OFF_BIT)
      , VERIFY_OFF      = (VERIFY      | OFF_BIT)
      , WRITE_FAULT_OFF = (WRITE_FAULT | OFF_BIT)

   } eState, eFlashState;
   UINT16 wFlashTimer;
   UINT16 wHornOnTimer;
   UINT8  bHighNibble;
   UINT8  bLowNibble;
   UINT16 wOption;
   UINT8  fLift: 1;
   UINT8  fRight: 1;
   UINT8  fLeft: 1;
   UINT8  fHigh: 1;
   UINT8  fHorn: 1;
 
   UINT8 u8DataNum: 2;
   UINT8 u8EN: 1;
   UINT16 bFlashTimer2;
   UINT8 u8_Button_EN: 1;
   
}      OAD_Local;
#endif



const UINT16 awDisplayToCode[72] =
{
   //to be compatible with version H1
              //display   type  dsc   US    alr   OL    bat   Kor   sensor
   0x2000,    //00        00    1     0     0     0     x     0     x
   0x2400,    //01        00    1     0     0     1     x     0     x
   0x2800,    //02        00    1     0     1     0     x     0     x
   0x2C00,    //03        00    1     0     1     1     x     0     x
   0x3000,    //04        00    1     1     0     0     x     0     x
   0x3400,    //05        00    1     1     0     1     x     0     x
   0x3800,    //06        00    1     1     1     0     x     0     x
   0x3C00,    //07        00    1     1     1     1     x     0     x
   0x0000,    //08        00    0     0     0     0     x     0     x
   0x0400,    //09        00    0     0     0     1     x     0     x
   0x0800,    //10        00    0     0     1     0     x     0     x
   0x0C00,    //11        00    0     0     1     1     x     0     x
   0x1000,    //12        00    0     1     0     0     x     0     x
   0x1400,    //13        00    0     1     0     1     x     0     x
   0x1800,    //14        00    0     1     1     0     x     0     x
   0x1C00,    //15        00    0     1     1     1     x     0     x
   0x7000,    //16        01    1     1     0     0     x     0     x
   0x7400,    //17        01    1     1     0     1     x     0     x
   0x7800,    //18        01    1     1     1     0     x     0     x
   0x7C00,    //19        01    1     1     1     1     x     0     x
   0x6000,    //20        01    1     0     0     0     x     0     x
   0x6400,    //21        01    1     0     0     1     x     0     x
   0x6800,    //22        01    1     0     1     0     x     0     x
   0x6C00,    //23        01    1     0     1     1     x     0     x
   0x5000,    //24        01    0     1     0     0     x     0     x
   0x5400,    //25        01    0     1     0     1     x     0     x
   0x5800,    //26        01    0     1     1     0     x     0     x
   0x5C00,    //27        01    0     1     1     1     x     0     x
   0x4000,    //28        01    0     0     0     0     x     0     x
   0x4400,    //29        01    0     0     0     1     x     0     x
   0x4800,    //30        01    0     0     1     0     x     0     x
   0x4C00,    //31        01    0     0     1     1     x     0     x
   0x6100,    //32        01    1     0     0     0     x     1     x
   0x6500,    //33        01    1     0     0     1     x     1     x
   0x6900,    //34        01    1     0     1     0     x     1     x
   0x6D00,    //35        01    1     0     1     1     x     1     x
   0x2100,    //36        00    1     0     0     0     x     1     x
   0x2500,    //37        00    1     0     0     1     x     1     x
   0x2900,    //38        00    1     0     1     0     x     1     x
   0x2D00,    //39        00    1     0     1     1     x     1     x
   0x4100,    //40        01    0     0     0     0     x     1     x
   0x4500,    //41        01    0     0     0     1     x     1     x
   0x4900,    //42        01    0     0     1     0     x     1     x
   0x4D00,    //43        01    0     0     1     1     x     1     x
   0x0100,    //44        00    0     0     0     0     x     1     x
   0x0500,    //45        00    0     0     0     1     x     1     x
   0x0900,    //46        00    0     0     1     0     x     1     x
   0x0D00,    //47        00    0     0     1     1     x     1     x
   0xE000,    //48        11    1     0     0     0     x     0     x
   0xE400,    //49        11    1     0     0     1     x     0     x
   0xE800,    //50        11    1     0     1     0     x     0     x
   0xEC00,    //51        11    1     0     1     1     x     0     x
   0xF000,    //52        11    1     1     0     0     x     0     x
   0xF400,    //53        11    1     1     0     1     x     0     x
   0xF800,    //54        11    1     1     1     0     x     0     x
   0xFC00,    //55        11    1     1     1     1     x     0     x
   0xC000,    //56        11    0     0     0     0     x     0     x
   0xC400,    //57        11    0     0     0     1     x     0     x
   0xC800,    //58        11    0     0     1     0     x     0     x
   0xCC00,    //59        11    0     0     1     1     x     0     x
   0xD000,    //60        11    0     1     0     0     x     0     x
   0xD400,    //61        11    0     1     0     1     x     0     x
   0xD800,    //62        11    0     1     1     0     x     0     x
   0xDC00,    //63        11    0     1     1     1     x     0     x
   0xE100,    //64        11    1     0     0     0     x     1     x
   0xE500,    //65        11    1     0     0     1     x     1     x
   0xE900,    //66        11    1     0     1     0     x     1     x
   0xED00,    //67        11    1     0     1     1     x     1     x
   0xC100,    //68        11    0     0     0     0     x     1     x
   0xC500,    //69        11    0     0     0     1     x     1     x
   0xC900,    //70        11    0     0     1     0     x     1     x
   0xCD00     //71        11    0     0     1     1     x     1     x
};

const UINT16 awCodeToDisplay[72] =
{
//==========================================================
//   type=00, US=0, Kor=0, dsc-alr-OL=000-111
//==========================================================
          //code     type  dsc   US    alr   OL    bat   Kor   sensor
    8,    //0x0000   00    0     0     0     0     x     0     x
    9,    //0x0400   00    0     0     0     1     x     0     x
   10,    //0x0800   00    0     0     1     0     x     0     x
   11,    //0x0C00   00    0     0     1     1     x     0     x
    0,    //0x2000   00    1     0     0     0     x     0     x
    1,    //0x2400   00    1     0     0     1     x     0     x
    2,    //0x2800   00    1     0     1     0     x     0     x
    3,    //0x2C00   00    1     0     1     1     x     0     x
//==========================================================
//   type=00, US=1, Kor=0, dsc-alr-OL=000-111
//==========================================================
          //code     type  dsc   US    alr   OL    bat   Kor   sensor
   12,    //0x1000   00    0     1     0     0     x     0     x
   13,    //0x1400   00    0     1     0     1     x     0     x
   14,    //0x1800   00    0     1     1     0     x     0     x
   15,    //0x1C00   00    0     1     1     1     x     0     x
    4,    //0x3000   00    1     1     0     0     x     0     x
    5,    //0x3400   00    1     1     0     1     x     0     x
    6,    //0x3800   00    1     1     1     0     x     0     x
    7,    //0x3C00   00    1     1     1     1     x     0     x
//==========================================================
//   type=00, US=0, Kor=1, dsc-alr-OL=000-111
//==========================================================
          //code     type  dsc   US    alr   OL    bat   Kor   sensor
   44,    //0x0100   00    0     0     0     0     x     1     x
   45,    //0x0500   00    0     0     0     1     x     1     x
   46,    //0x0900   00    0     0     1     0     x     1     x
   47,    //0x0D00   00    0     0     1     1     x     1     x
   36,    //0x2100   00    1     0     0     0     x     1     x
   37,    //0x2500   00    1     0     0     1     x     1     x
   38,    //0x2900   00    1     0     1     0     x     1     x
   39,    //0x2D00   00    1     0     1     1     x     1     x
//==========================================================
//   type=01, US=0, Kor=0, dsc-alr-OL=000-111
//==========================================================
          //code     type  dsc   US    alr   OL    bat   Kor   sensor
   28,    //0x4000   01    0     0     0     0     x     0     x
   29,    //0x4400   01    0     0     0     1     x     0     x
   30,    //0x4800   01    0     0     1     0     x     0     x
   31,    //0x4C00   01    0     0     1     1     x     0     x
   20,    //0x6000   01    1     0     0     0     x     0     x
   21,    //0x6400   01    1     0     0     1     x     0     x
   22,    //0x6800   01    1     0     1     0     x     0     x
   23,    //0x6C00   01    1     0     1     1     x     0     x
//==========================================================
//   type=01, US=1, Kor=0, dsc-alr-OL=000-111
//==========================================================
          //code     type  dsc   US    alr   OL    bat   Kor   sensor
   24,    //0x5000   01    0     1     0     0     x     0     x
   25,    //0x5400   01    0     1     0     1     x     0     x
   26,    //0x5800   01    0     1     1     0     x     0     x
   27,    //0x5C00   01    0     1     1     1     x     0     x
   16,    //0x7000   01    1     1     0     0     x     0     x
   17,    //0x7400   01    1     1     0     1     x     0     x
   18,    //0x7800   01    1     1     1     0     x     0     x
   19,    //0x7C00   01    1     1     1     1     x     0     x
//==========================================================
//   type=01, US=0, Kor=1, dsc-alr-OL=000-111
//==========================================================
          //code     type  dsc   US    alr   OL    bat   Kor   sensor
   40,    //0x4100   01    0     0     0     0     x     1     x
   41,    //0x4500   01    0     0     0     1     x     1     x
   42,    //0x4900   01    0     0     1     0     x     1     x
   43,    //0x4D00   01    0     0     1     1     x     1     x
   32,    //0x6100   01    1     0     0     0     x     1     x
   33,    //0x6500   01    1     0     0     1     x     1     x
   34,    //0x6900   01    1     0     1     0     x     1     x
   35,    //0x6D00   01    1     0     1     1     x     1     x
//==========================================================
//   type=11, US=0, Kor=0, dsc-alr-OL=000-111
//==========================================================
          //code     type  dsc   US    alr   OL    bat   Kor   sensor
   56,    //0xC000   11    0     0     0     0     x     0     x
   57,    //0xC400   11    0     0     0     1     x     0     x
   58,    //0xC800   11    0     0     1     0     x     0     x
   59,    //0xCC00   11    0     0     1     1     x     0     x
   48,    //0xE000   11    1     0     0     0     x     0     x
   49,    //0xE400   11    1     0     0     1     x     0     x
   50,    //0xE800   11    1     0     1     0     x     0     x
   51,    //0xEC00   11    1     0     1     1     x     0     x
//==========================================================
//   type=11, US=1, Kor=0, dsc-alr-OL=000-111
//==========================================================
          //code     type  dsc   US    alr   OL    bat   Kor   sensor
   60,    //0xD000   11    0     1     0     0     x     0     x
   61,    //0xD400   11    0     1     0     1     x     0     x
   62,    //0xD800   11    0     1     1     0     x     0     x
   63,    //0xDC00   11    0     1     1     1     x     0     x
   52,    //0xF000   11    1     1     0     0     x     0     x
   53,    //0xF400   11    1     1     0     1     x     0     x
   54,    //0xF800   11    1     1     1     0     x     0     x
   55,    //0xFC00   11    1     1     1     1     x     0     x
//==========================================================
//   type=11, US=0, Kor=1, dsc-alr-OL=000-111
//==========================================================
          //code     type  dsc   US    alr   OL    bat   Kor   sensor
   68,    //0xC100   11    0     0     0     0     x     1     x
   69,    //0xC500   11    0     0     0     1     x     1     x
   70,    //0xC900   11    0     0     1     0     x     1     x
   71,    //0xCD00   11    0     0     1     1     x     1     x
   64,    //0xE100   11    1     0     0     0     x     1     x
   65,    //0xE500   11    1     0     0     1     x     1     x
   66,    //0xE900   11    1     0     1     0     x     1     x
   67     //0xED00   11    1     0     1     1     x     1     x
};

static void option_display(void);
static void adjust_value(void);
static UINT8 change_value_high(UINT8 bValue);
static UINT8 change_value_low(UINT8 bValue);
static  void save_options(void);

static UINT8
change_value_high(UINT8 bValue)
{

   if(SCAN_RIGHT_ON && (bValue < 15))
   {
      bValue++;
   }
   else if(SCAN_LEFT_ON  && (bValue >= 1))
   {
      bValue--;
   }
   return bValue;
}

static UINT8
change_value_low(UINT8 bValue)
{

   if(SCAN_RIGHT_ON && (bValue < 9))
   {
      bValue++;
   }
   else if(SCAN_LEFT_ON  && (bValue >= 1))
   {
      bValue--;
   }

   return bValue;
}

static UINT8
change_hex_value_low(UINT8 bValue)
{

   if(SCAN_RIGHT_ON && (bValue < 15))
   {
      bValue++;
   }
   else if(SCAN_LEFT_ON  && (bValue >= 1))
   {
      bValue--;
   }

   return bValue;
}

void
adjust_value(void)
{
   if(OAD_Local.bHighNibble >= 15)
   {
      OAD_Local.bHighNibble = 15;
      if(OAD_Local.bLowNibble > 1)
      {
         OAD_Local.bLowNibble = 1;
      }
   }
   if((OAD_Local.bHighNibble == 7) && (OAD_Local.bLowNibble > 1))
   {
      OAD_Local.bLowNibble = 1;
   }
}

void
decode_option(void)
{
   UINT8 bTemp;
   union
   {
      UINT16  word;
      lift_options_t bits;
   } uOption;
   uOption.word = OAD_Local.wOption;
   bTemp = ((UINT8)uOption.bits.fType / 2 + (UINT8)uOption.bits.fType % 2) * 24 +
           ((UINT8)uOption.bits.fUS_option + (UINT8)uOption.bits.fKorea_option * 2) * 8 +
           (UINT8)uOption.bits.fDescent_delay * 4 +
           (UINT8)uOption.bits.fMotion_alarm * 2 +
           (UINT8)uOption.bits.fOverload2_cutout;
   bTemp = awCodeToDisplay[bTemp];
   if(uOption.bits.fSensorType)
   {
      bTemp += 80;
   }

   OAD_Local.bHighNibble = bTemp / 10;
   OAD_Local.bLowNibble  = bTemp % 10;
}

void save_options(void)
{
   UINT8 bTemp;
   UINT8 ix;
   UINT8 * pb;
   UINT8 * ps;
   UINT16 wOption;

   //get new option
   bTemp = (OAD_Local.bHighNibble * 10) + OAD_Local.bLowNibble;
   if(bTemp >= 80) // sensor type is current
   {
      wOption = awDisplayToCode[bTemp - 80];
      wOption |= 0x0080;
   }
   else
   {
      wOption = awDisplayToCode[bTemp];
   }
   // if change machine type, load parameter
   if((OAD_Local.wOption & 0xC000) != (wOption & 0xC000))
   {
      //restore default paramters
      switch((wOption >> 14) & 3)
      {
         default:
         case LIFT_TYPE_SMALL_SLAB:
            ps = (UINT8 *)&small_slab_setup;
            break;

         case LIFT_TYPE_ELEC1:
            ps = (UINT8 *)&electric1_setup;
            break;

         /*case LIFT_TYPE_ELEC2:
            ps = (UINT8 *)&electric2_setup;
            break;*/

         case LIFT_TYPE_ELEC3:
            ps = (UINT8 *)&electric3_setup;
            break;
       }
       pb = (UINT8 *)&lift_setup;
       for ( ix = 0; ix < sizeof( struct nvm_lift_setup); ix++)
       {
          *pb++ = *ps++;
       }
       lift_setup.bMajor = IMAGE_Descr.szName[ 0];
       lift_setup.bMinor = IMAGE_Descr.szName[ 1];
   }
   //if change country, store default paramter
   if((OAD_Local.wOption & 0x5100) != (wOption & 0x5100))
   {

       //restore US default (only ELEC1 or ELEC3)
       if((wOption & 0x5000) == 0x5000)
      {
          lift_setup.drive_rised_curve.bAccelIncrement = 6;
          lift_setup.drive_rised_curve.bDecelIncrement = 12;
          lift_setup.drive_rised_curve.bPeriod = 40;
       }
       //restore Korea default
       else if(wOption & 0x0100)
       {
          //lift_setup.drive_rised_curve.bPwmPosAdjust = 0;
          //lift_setup.drive_rised_curve.bPwmNegAdjust = 0;
       }
       //write parameters to EEPROM
       record_write_verify( lift_setup.bLiftType, sizeof( struct nvm_lift_setup), (UINT8 *)&lift_setup);
    }

    OAD_Local.wOption &= 0x0240;  // Preserve the Battery Drain and Foot Plate setting.
    OAD_Local.wOption |= wOption;
    record_write( RECORD_MAGIC_OPTION_1, 2,  (UINT8 *)&OAD_Local.wOption);
    delay_mSec(3);
    record_write( RECORD_MAGIC_OPTION_2, 2,  (UINT8 *)&OAD_Local.wOption);
    delay_mSec(3);
    record_write( RECORD_MAGIC_OPTION_3, 2,  (UINT8 *)&OAD_Local.wOption);

}

// Checks if the option code value is a valid one.
UINT8
Check_Option_Code(UINT16 OptionCodeValue)
{
   lift_options_t *newOptions = (lift_options_t*)&OptionCodeValue;

   if((newOptions->fUS_option && newOptions->fKorea_option)    // cannot select US and Korea at same time
      || (newOptions->fSpare != 0))                          // spare bit must be 0
   {
      return FALSE;
   }
   else
   {
      return TRUE;
   }
}

// it should be same clock as switches scan
void
option_adjust(void)
{
   UINT16 wTemp;
   UINT16 wTemp2;
   UINT16 wTemp3;

   switch(OAD_Local.eState)
   {
      default:
      case SC:
         OAD_Local.wOption = LIFT_OPTIONS_UINT16;
         decode_option();
         OAD_Local.eState = SC_SHOW;
         break;

      case SC_SHOW:
         if(0 == SW_HIGH)
         {
            OAD_Local.eState = SHOW_VALUE;
         }

         break;

      case SHOW_VALUE:
         if(SW_HIGH)
         {
            OAD_Local.eState = SC;
         }
         else if(SCAN_LIFT_ON)
         {
            OAD_Local.eState = HIGH_NIBBLE;
            OAD_Local.wHornOnTimer = 0;
         }
         else if(SCAN_LIFT_OFF)
         {
            OAD_Local.eState = LOW_NIBBLE;
            OAD_Local.wHornOnTimer = 0;
         }

         break;

      case LOW_NIBBLE:
         OAD_Local.bLowNibble = change_value_low(OAD_Local.bLowNibble);
         adjust_value();

         if(SW_HIGH)
         {
            OAD_Local.eState = SC;
         }
         else if(LIFT_DRIVE)
         {
            OAD_Local.eState = HIGH_NIBBLE;
            OAD_Local.wHornOnTimer  = 0;
         }
         else if(SW_HORN)
         {
            OAD_Local.wHornOnTimer++;

            if(OAD_Local.wHornOnTimer  > (UINT16)SAVE_TIME)
            {
               save_options();
               OAD_Local.eState = VERIFY;
               OAD_Local.wHornOnTimer = 0;
            }
         }
         else if(OAD_Local.fHorn && OAD_Local.wHornOnTimer < OPTION_CLICK_TIME)
         {
            OAD_Local.wOption ^= 0x0200;
            OAD_Local.wHornOnTimer  = 0;
         }
         else
         {
            OAD_Local.wHornOnTimer  = 0;
         }

         break;

      case HIGH_NIBBLE:
         OAD_Local.bHighNibble = change_value_high(OAD_Local.bHighNibble);
         adjust_value();

         if(SW_HIGH)
         {
            OAD_Local.eState = SC;
         }
         else if(!LIFT_DRIVE)
         {
            OAD_Local.eState = LOW_NIBBLE;
            OAD_Local.wHornOnTimer  = 0;
         }
         else if(SW_HORN)
         {
            OAD_Local.wHornOnTimer++;

            if(OAD_Local.wHornOnTimer  > (UINT16)SAVE_TIME)   // 2 seconds
            {
               save_options();
               OAD_Local.eState = VERIFY;
               OAD_Local.wHornOnTimer = 0;
            }
         }
         else if(OAD_Local.fHorn && OAD_Local.wHornOnTimer < OPTION_CLICK_TIME)
         {
            OAD_Local.wOption ^= 0x0040;
            OAD_Local.wHornOnTimer  = 0;
         }
         else
         {
            OAD_Local.wHornOnTimer  = 0;
         }

         break;

      case VERIFY:
         wTemp = OAD_Local.wOption + 1;
         wTemp2 = wTemp;
         wTemp3 = wTemp;

         if((EEPROM_OK != record_read(RECORD_MAGIC_OPTION_1, 2, (UINT8 *)&wTemp))
            && (EEPROM_OK != record_read(RECORD_MAGIC_OPTION_2, 2, (UINT8 *)&wTemp2))
            && (EEPROM_OK != record_read(RECORD_MAGIC_OPTION_3, 2, (UINT8 *)&wTemp3)))
         {
            OAD_Local.wOption = 0;
            OAD_Local.eState = WRITE_FAULT;
         }
         //            else if ( bTemp != OAD_Local.bOption )
         else if((wTemp != OAD_Local.wOption)
                 && (wTemp2 != OAD_Local.wOption)
                 && (wTemp3 != OAD_Local.wOption))
         {
            OAD_Local.eState = WRITE_FAULT;
         }
         else
         {
            OAD_Local.eState = SHOW_VALUE1;
         }

         decode_option();
         break;

      case SHOW_VALUE1:
         if(0 == SW_HORN)
         {
            OAD_Local.eState = SHOW_VALUE;
         }

         break;

      case WRITE_FAULT:
         if(0 == SW_HORN)
         {
            OAD_Local.wHornOnTimer++;

            if(OAD_Local.wHornOnTimer > 10)
            {
               OAD_Local.eState = SHOW_VALUE;
            }
         }

         break;
   }

   option_display();

   OAD_Local.fLift  = LIFT_DRIVE;
   OAD_Local.fRight = SW_RIGHT;
   OAD_Local.fLeft  = SW_LEFT;
   OAD_Local.fHigh  = SW_HIGH;
   OAD_Local.fHorn  = SW_HORN;

}

static void option_display(void)
{
   if((OAD_Local.eFlashState & ~OFF_BIT) != OAD_Local.eState)
   {
      OAD_Local.eFlashState =  OAD_Local.eState | OFF_BIT;
      OAD_Local.wFlashTimer = 0;
   }

   switch(OAD_Local.eFlashState)
   {
      default:
      case SC:
      case SC_OFF:
      case SC_SHOW:
      case SC_SHOW_OFF:
         Display.field.bSevenLeft  =  Seg7_Asc[ 'S'];
         Display.field.bSevenRight =  Seg7_Asc[ 'C'];
         break;

      case WRITE_FAULT:
      case WRITE_FAULT_OFF:
         Display.field.bSevenLeft  =  Seg7_Asc[ 'E'];
         Display.field.bSevenRight =  Seg7_Asc[ 'r'];
         break;

      case LOW_NIBBLE_OFF:
         Display.field.bSevenLeft  = Seg7_Hex[ OAD_Local.bHighNibble];
         Display.field.bSevenRight = 0;
         Display.led.pd_r  = ((OAD_Local.wOption & 0x0200)) ? LED_ON : LED_OFF;
         Display.led.pd_l  = ((OAD_Local.wOption & 0x0040)) ? LED_ON : LED_OFF;
         break;

      case HIGH_NIBBLE_OFF:
         Display.field.bSevenLeft  = 0;
         Display.field.bSevenRight = Seg7_Hex[ OAD_Local.bLowNibble];
         Display.led.pd_r  = ((OAD_Local.wOption & 0x0200)) ? LED_ON : LED_OFF;
         Display.led.pd_l  = ((OAD_Local.wOption & 0x0040)) ? LED_ON : LED_OFF;
         break;

      case LOW_NIBBLE:
      case SHOW_VALUE:
      case SHOW_VALUE_OFF:
      case HIGH_NIBBLE:
      case SHOW_VALUE1:
      case SHOW_VALUE1_OFF:
      case VERIFY:
      case VERIFY_OFF:
         Display.field.bSevenLeft  = Seg7_Hex[ OAD_Local.bHighNibble ];
         Display.field.bSevenRight = Seg7_Hex[ OAD_Local.bLowNibble ];
         Display.led.pd_r  = ((OAD_Local.wOption & 0x0200)) ? LED_ON : LED_OFF;
         Display.led.pd_l  = ((OAD_Local.wOption & 0x0040)) ? LED_ON : LED_OFF;
         break;
   }

   OAD_Local.wFlashTimer++;

   if(OAD_Local.wFlashTimer > FLASH_TIME)
   {
      OAD_Local.eFlashState ^= OFF_BIT;
      OAD_Local.wFlashTimer = 0;
   }
}

void
GPS_unlock_temporary_randomcode_display(void)
{
   static UINT8 ps = 0;
  
   if(!SW_LIFT && !SW_HORN && !SW_DRIVE && !SW_HIGH) OAD_Local.u8EN = 1;
	   
   if(SW_LIFT && OAD_Local.u8EN) 
   {
	   ps++;
	   OAD_Local.u8EN = 0;
   }
   if(ps > 3) ps = 0;
   switch(ps)
   {
	  default:
      case 0:
        DISPLAY_Platform.Display.field.bSevenLeft  = Seg7_Asc[ 'H' ];
		DISPLAY_Platform.Display.field.bSevenRight = Seg7_Asc[ '7' ];
		DISPLAY_Platform.Display.led.pd_l = 0;
		if(DISPLAY_Platform.bFlashTimer < DISPLAY_250MS)
		{
			DISPLAY_Platform.Display.led.pd_r = 1;
		}
		else
		{
			DISPLAY_Platform.Display.led.pd_r = 0;
		}
		break;	
	  case 1:
		DISPLAY_Platform.Display.field.bSevenLeft  = Seg7_Hex[GPS_DATA.u8GPS_unlock_temporary_randomcode1];
		DISPLAY_Platform.Display.field.bSevenRight = Seg7_Hex[GPS_DATA.u8GPS_unlock_temporary_randomcode2];
		if(DISPLAY_Platform.bFlashTimer < DISPLAY_250MS)
		{
			DISPLAY_Platform.Display.led.pd_r = 1;
		}
		else
		{
			DISPLAY_Platform.Display.led.pd_r = 0;
		}
		break;
	  case 2:
		DISPLAY_Platform.Display.field.bSevenLeft  = Seg7_Hex[GPS_DATA.u8GPS_unlock_temporary_randomcode3];
		DISPLAY_Platform.Display.field.bSevenRight = Seg7_Hex[GPS_DATA.u8GPS_unlock_temporary_randomcode4];
		if(DISPLAY_Platform.bFlashTimer < DISPLAY_250MS)
		{
		 DISPLAY_Platform.Display.led.pd_r = 1;
		}
		else
		{
		 DISPLAY_Platform.Display.led.pd_r = 0;
		}
		break;
	  case 3:
		DISPLAY_Platform.Display.field.bSevenLeft  = Seg7_Hex[GPS_DATA.u8GPS_unlock_temporary_randomcode5];
		DISPLAY_Platform.Display.field.bSevenRight = Seg7_Hex[GPS_DATA.u8GPS_unlock_temporary_randomcode6];
		if(DISPLAY_Platform.bFlashTimer < DISPLAY_250MS)
		{
		 DISPLAY_Platform.Display.led.pd_r = 1;
		}
		else
		{
		 DISPLAY_Platform.Display.led.pd_r = 0;
		}
		break;
   }
   if(SW_HORN && OAD_Local.u8EN ) 
   {
   	  MAIN_Data.eState = MAIN_GPS_UNLOCK_TEMPORARY_CHECK_CODE;
	  OAD_Local.u8EN = 0;
   }
}

void
GPS_unlock_temporary_checkcode_display(void)
{
	static UINT8 ps = 0;
	static UINT8 mComplete = 0;
	static UINT8 u8KeyCheck_Result;

	if(mComplete)
	{
		if(u8KeyCheck_Result==1)
		{
			DISPLAY_Platform.Display.field.bSevenLeft  = Seg7_Asc['S'];
			DISPLAY_Platform.Display.field.bSevenRight  = Seg7_Asc['C'];
		}
		else
		{
			DISPLAY_Platform.Display.field.bSevenLeft  = Seg7_Asc['E'];
			DISPLAY_Platform.Display.field.bSevenRight  = Seg7_Asc['r'];
		}
		return;
	}
	if(!SW_LIFT && !SW_HORN && !SW_DRIVE && !SW_HIGH) OAD_Local.u8EN = 1;
	
	if(SW_LIFT && OAD_Local.u8EN) 
	{
		ps++;
		OAD_Local.u8EN = 0;
	}
	if(ps > 3) ps = 0;
	switch(ps)
	{
		default:
		case 0:
			DISPLAY_Platform.Display.field.bSevenLeft  = Seg7_Asc[ '1' ];
			GPS_DATA.u8GPS_unlock_temporary_checkcode1 = change_hex_value_low(GPS_DATA.u8GPS_unlock_temporary_checkcode1);
			//adjust_value2();
			if(DISPLAY_Platform.bFlashTimer < DISPLAY_250MS)
			{
				DISPLAY_Platform.Display.field.bSevenRight  = Seg7_Hex[GPS_DATA.u8GPS_unlock_temporary_checkcode1];
				DISPLAY_Platform.Display.led.pd_r = 1;
			}
			else
			{
				DISPLAY_Platform.Display.field.bSevenRight  = 0;
				DISPLAY_Platform.Display.led.pd_r = 0;
			}
			break;	
		case 1:
			GPS_DATA.u8GPS_unlock_temporary_checkcode2 = change_hex_value_low(GPS_DATA.u8GPS_unlock_temporary_checkcode2);
			//adjust_value2();
			DISPLAY_Platform.Display.field.bSevenLeft  = Seg7_Asc[ '2' ];
			if(DISPLAY_Platform.bFlashTimer < DISPLAY_250MS)
			{
				DISPLAY_Platform.Display.field.bSevenRight  = Seg7_Hex[GPS_DATA.u8GPS_unlock_temporary_checkcode2];
				DISPLAY_Platform.Display.led.pd_r = 1;
			}
			else
			{
				DISPLAY_Platform.Display.field.bSevenRight  = 0;
				DISPLAY_Platform.Display.led.pd_r = 0;
			}
			break;
		case 2:
			GPS_DATA.u8GPS_unlock_temporary_checkcode3 = change_hex_value_low(GPS_DATA.u8GPS_unlock_temporary_checkcode3);
			//adjust_value2();
			DISPLAY_Platform.Display.field.bSevenLeft  = Seg7_Asc[ '3' ];
			if(DISPLAY_Platform.bFlashTimer < DISPLAY_250MS)
			{
				DISPLAY_Platform.Display.field.bSevenRight  = Seg7_Hex[GPS_DATA.u8GPS_unlock_temporary_checkcode3];
				DISPLAY_Platform.Display.led.pd_r = 1;
			}
			else
			{
				DISPLAY_Platform.Display.field.bSevenRight  = 0;
				DISPLAY_Platform.Display.led.pd_r = 0;
			}
			break;
		case 3:
			GPS_DATA.u8GPS_unlock_temporary_checkcode4 = change_hex_value_low(GPS_DATA.u8GPS_unlock_temporary_checkcode4);
			//adjust_value2();
			DISPLAY_Platform.Display.field.bSevenLeft  = Seg7_Asc[ '4' ];
			if(DISPLAY_Platform.bFlashTimer < DISPLAY_250MS)
			{
				DISPLAY_Platform.Display.field.bSevenRight  = Seg7_Hex[GPS_DATA.u8GPS_unlock_temporary_checkcode4];
				DISPLAY_Platform.Display.led.pd_r = 1;
			}
			else
			{
				DISPLAY_Platform.Display.field.bSevenRight  = 0;
				DISPLAY_Platform.Display.led.pd_r = 0;
			}
			break;
	}
	if(SW_HORN && OAD_Local.u8EN) 
	{
	    UINT16 u16_passcode = 0; //0-FFFF
		

		mComplete = 1;
		u16_passcode =GPS_DATA.u8GPS_unlock_temporary_checkcode1*4096+GPS_DATA.u8GPS_unlock_temporary_checkcode2*256+GPS_DATA.u8GPS_unlock_temporary_checkcode3*16+GPS_DATA.u8GPS_unlock_temporary_checkcode4;
   
        u8KeyCheck_Result =n_ECULockLibTempLockSigIn(u16_passcode);
		if(u8KeyCheck_Result==1)
		{
			DISPLAY_Platform.Display.field.bSevenLeft  = Seg7_Asc['S'];
			DISPLAY_Platform.Display.field.bSevenRight  = Seg7_Asc['C'];
		}
		else
		{
			DISPLAY_Platform.Display.field.bSevenLeft  = Seg7_Asc['E'];
			DISPLAY_Platform.Display.field.bSevenRight  = Seg7_Asc['r'];
		}
	}
	OAD_Local.fLift  = LIFT_DRIVE;
	OAD_Local.fRight = SW_RIGHT;
	OAD_Local.fLeft  = SW_LEFT;
	OAD_Local.fHigh  = SW_HIGH;
	OAD_Local.fHorn  = SW_HORN;
}



